import random #打乱数组用
import pgzrun #pygamezero
import time

def gifrc(r, c): #从xy坐标获取index
    return r * SIZE + c

def grcfi(idx): #从index获取xy坐标
    r = int(idx / SIZE)
    c = int(idx % SIZE)
    return r, c

num_size = 160 #数字大小
SIZE=3 #有多少行
WIDTH = SIZE*num_size #长
HEIGHT = SIZE*num_size #宽
BACK_COLOR = (200,75,150) #没啥用的背景色
flag=False #判断是否完成
move_finished = True

board = Actor('board') #没啥用的背景
board.pos = 480 // 2, 480 // 2
space = (2,2) #记录空格位置

nums = [] #存放滑块演员们的列表
offset = 0 #间距，我没设
num_list=[x+1 for x in range(SIZE*SIZE)] #生成一个数字列表
random.shuffle(num_list) #打乱这个列表生成谜题
#print(num_list)
for i in range(SIZE*SIZE): #遍历列表，生成滑块
    r = i % SIZE
    c = i // SIZE
    if num_list[i]==SIZE*SIZE: #我这里把空格图片设为了9
        space=grcfi(i) #记录空格位置
    num = Actor(str(num_list[i])) #记录滑块
    num.pos = r * num_size + num_size / 2 + offset, c * num_size + num_size / 2 + offset #计算坐标
    nums.append(num) #保存

def check(): #检测谜题是否完成
    for i in range(SIZE*SIZE):
        if not (int(nums[i].image) == i+1): #我这里用的是image的名字
            return False #没好
    return True #好了

def on_mouse_down(pos):
    global space,flag, move_finished
    if flag or (not move_finished): #如果已经完成或上次移动未完成，点击无效
        return
    j=pos[0]//num_size #计算当前位置的网格坐标
    i=pos[1]//num_size
#    print(i,j)
    if space in [(i-1,j),(i+1,j),(i,j-1),(i,j+1)]: #如果空格在点击位置周围
        move_finished=False
        animate(nums[gifrc(i,j)],pos=nums[gifrc(space[0],space[1])].pos,duration=0.1) #animate，pygamezero自带动画函数，详见附录一，在视觉上把点击滑块移到空格处
#        time.sleep(1)
        def finished():
            global move_finished
            move_finished=True
        animate(nums[gifrc(space[0],space[1])],pos=nums[gifrc(i,j)].pos,duration=0.1,on_finished=finished) #同上，在视觉上把空格移动到点击处
        nums[gifrc(space[0],space[1])],nums[gifrc(i,j)]=nums[gifrc(i,j)],nums[gifrc(space[0],space[1])] #在实际上交换两个滑块
        space=(i,j) #将空格位置改为点击位置
       
def update():
    pass

def draw():
    global flag
    if check() and (not flag): #检查是否完成
        flag=True
        print("-----------------WIN-----------------")
    screen.clear()
    screen.fill(BACK_COLOR)
    board.draw()
    for n in nums: #绘制
        n.draw()

pgzrun.go()

#附录一
'''
    animate参数如下：
     -object 移动对象，为Actor
     -tween 移动模式，默认为’linear‘，线性
     -duration 动画持续时间，默认值为1
     -on_finished 动画结束时的函数
     -targets ？？？
     -pos 移动到的坐标
    更多详见 https://pygame-zero.readthedocs.io/zh_CN/latest/builtins.html#id17
'''